// poj3687
// 题意：给点n(<=200)个位置，要放重量为1..n互不相同的物体，
//       现在已知m(<=40000)条小于关系(a, b)，即某个位置a放的物体
//       重量要小于位置b。问是否可以放，如果可以，输出一个字典序
//       （从1号标签开始，按数值比较大小）最小的方案。
//
// 题解：前面部分可以用floyd' algorithm搞定图的传递闭包。现在有了
//       所有可以推导出来的大小关系后，要放出一个字典序最小的方案。
//       我们可以按照“重于”（大于）关系建立一个拓扑图，然后不断取
//       入度为零的点然后把当前最大的标号放当前价值。价值从n减到1。
//       这样就可以。
//       为什么按“轻于”（小于）关系建立拓扑图不行呢？这里有组反例：
//       
//       2
//       
//       5 4
//       1 4
//       4 2
//       5 3
//       3 2
//       
//       5 3
//       1 4
//       4 2
//       3 5
//
//       因为保证当前入度为零的点的较小编号放最小值不一定是全局字典序
//       最小，比如1可能在某个5后面，然后5和2是入度为零的点，这样就把
//       较小的给了2。
//       那为什么反过来就对了呢。我们可以这样证明：
//       对于某一次入度为零的点，如果当前可放的最大值不给最大标号，
//       那么说明当前最大值给了一个较小的标号(way2)，而本来它应该可以更小，
//       按字典序比较后者比前者大。然后接下来，我们只需要不断模仿从
//       分叉点开始(way2)取的点，这样在再次汇合前，按找取最大标号方式取的
//       都比way2小一个下标，所以是最优的。
//
//       至于最优的也一定是这么产生的证明也很简单，假设最优方案和我们
//       上述算法产生的序列不相等。那么最优序列按重量大到小倒过来从第
//       一个不想等的下标开始，就是上述我们讨论的分叉点，所以最优序列
//       小于我们产生的序列，矛盾。
//
// run: $exec < input
#include <iostream>
#include <vector>
#include <queue>

int const maxn = 202;
bool vis[maxn];
int lighter[maxn][maxn];
int indegree[maxn];
int ans[maxn];
int n, m;

void init()
{
	for (int i = 0; i <= n; i++) {
		vis[i] = false;
		indegree[i] = 0;
		for (int j = 0; j <= n; j++) lighter[i][j] = -1;
	}
}

int main()
{
	std::ios::sync_with_stdio(false);
	int T; std::cin >> T;
	while (T--) {
		std::cin >> n >> m;
		init();
		bool sol = true;
		for (int i = 0, x, y; i < m; i++) {
			std::cin >> x >> y;
			x--; y--;
			if (!lighter[x][y] || x == y) sol = false;
			lighter[x][y] = 1;
			lighter[y][x] = 0;
		}

		if (!sol) { std::cout << "-1\n"; continue; }

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				for (int k = 0; k < n; k++) {
					if (lighter[i][k] < 0 || lighter[j][k] < 0) continue;
					if (lighter[i][k] && lighter[k][j]) {
						if (!lighter[i][j]) { sol = false; break; }
						lighter[i][j] = 1;
						lighter[j][i] = 0;
					}
					if (lighter[j][k] && lighter[k][i]) {
						if (lighter[i][j] == 1) { sol = false; break; }
						lighter[i][j] = 0;
						lighter[j][i] = 1;
					}
				}
				if (i == j && lighter[i][j] != -1) sol = false;
				if (!sol) break;
			}
			if (!sol) break;
		}

		if (!sol) { std::cout << "-1\n"; continue; }

		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				if (lighter[i][j] == 0) indegree[j]++;

		std::priority_queue<int> pq;
		for (int i = 0; i < n; i++)
			if (!indegree[i]) { pq.push(i); vis[i] = true; }
		int weight = n;
		while (!pq.empty()) {
			int now = pq.top(); pq.pop();
			ans[now] = weight--;
			for (int i = 0; i < n; i++)
				if (!vis[i] && !lighter[now][i]) {
					indegree[i]--;
					if (!indegree[i]) { pq.push(i); vis[i] = true; }
				}
		}

		std::cout << ans[0];
		for (int i = 1; i < n; i++) std::cout << ' ' << ans[i];
		std::cout << '\n';
	}
}

